﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using volva.Models;

namespace volva.Services
{
    public class StationService
    {
        /// <summary>
        /// Changes a stations basic information
        /// </summary>
        /// <param name="model">The model of the affected station</param>
        static public void ChangeInfo(Station model)
        {
            Station station = StationService.GetStationByID(model.id);

            station = model;

            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Adds a video to a station
        /// </summary>
        /// <param name="model">The model for the video that is to be added</param>
        /// <param name="stationId">The ID number for the station that the video will be added to</param>
        static public void AddVideo(Video model, int stationId)
        {
            // Should this even take in stationId? The Video model contains a stationId,
            // so it seems kind of redundant..

            // Missing: A table that holds what video's are on what station.
            // Viktor is taking a nap and then he will free us from ignorance
            // with his wise wisdom.

            model.Station_id = stationId;
            DataService.ddc.Videos.InsertOnSubmit(model);
            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Deletes a video
        /// </summary>
        /// <param name="videoId">The ID of the video that is to be deleted</param>
        static public void DeleteVideo(int videoId)
        {
            Video video = StationService.GetVideoByID(videoId);

            foreach (Comment comment in video.Comments)
            {
                DataService.ddc.Comments.DeleteOnSubmit(comment);
            }
            foreach (ScheduleItem si in video.ScheduleItems)
            {
                DataService.ddc.ScheduleItems.DeleteOnSubmit(si);
            }
            DataService.ddc.Videos.DeleteOnSubmit(video);
            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Adds a station
        /// </summary>
        /// <param name="model">The model of the station that is to be created</param>
        static public void AddStation(Station model)
        {
            DataService.ddc.Stations.InsertOnSubmit(model);
            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Deletes a station
        /// </summary>
        /// <param name="stationId">The ID of the station that is to be deleted</param>
        static public void DeleteStation(int stationId)
        {
            Station station = StationService.GetStationByID(stationId);

            DataService.ddc.Stations.DeleteOnSubmit(station);
            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Adds a rating to a station
        /// </summary>
        /// <param name="stationId">The ID of the station</param>
        /// <param name="rating">The rating a user has decided to give a station</param>
        static public void AddStationRating(int stationId, int rating)
        {
            Station station = StationService.GetStationByID(stationId);

            station.ratingSum += rating;    // Add the rating to the rating sum
            station.ratingCount++;          // Increment the rating count by one

            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Add one (1) to a videos view count.
        /// </summary>
        /// <param name="videoId">The ID of the video in question</param>
        static public void AddVideoView(int videoId)
        {
            Video video = StationService.GetVideoByID(videoId);
            /*Video video =
                (from v in DataService.ddc.Videos
                 where v.id == videoId
                 select v).SingleOrDefault();*/

            if (video.viewCount == null)
            {
                video.viewCount = 0;
            }
            video.viewCount++;      // Increment the video count by one

            DataService.ddc.SubmitChanges();
        }

        static public void AddStationView(int stationId)
        {
            Station station = StationService.GetStationByID(stationId);

            if (station.viewCount == null)
            {
                station.viewCount = 0;
            }
            else
            {
                station.viewCount = station.viewCount + 1;
            }   

            station.viewCount = station.viewCount + 1;
            DataService.ddc.SubmitChanges();
        }
        /// <summary>
        /// Marks a video as reported
        /// </summary>
        /// <param name="videoId">The ID of the video in question</param>
        /// <param name="message">The message that a user wrote when reporting the video</param>
        static public void ReportVideo(int videoId, string message)
        {
            Video video = StationService.GetVideoByID(videoId);

            int stationAdminId =
                Convert.ToInt32(
                from wbs in DataService.ddc.WebUserRoles
                where wbs.Station_id == video.Station_id && wbs.access == 2
                select wbs.WebUser_id
                );

            string stationName =
                (from s in DataService.ddc.Stations
                where s.id == video.Station_id
                select s.name).ToString();

            DataService.ddc.SubmitChanges();

            // Missing: The name of the video in the database

            Message spamMessage = new Message();
            spamMessage.subject = "A video on your station has been reported as inappropriate";
            spamMessage.body =  "The video: " + video.name  + " on your station: " + stationName + " has been reported by a user as inappropriate. \r\n" +
                                "The message the user reported with the video is as follows: \r\n" +
                                message;
            spamMessage.WebUser_to_id = stationAdminId;

            MessageService.Send(spamMessage);

            video.spamReportCount++;        // Increment the spam count by one
        }
        /// <summary>
        /// Looks up a Station object from a station ID
        /// </summary>
        /// <param name="stationID">The ID of the station that is required</param>
        /// <returns>A station object with the corresponding ID</returns>
        static public Station GetStationByID(int stationID)
        {
            return
                (from s in DataService.ddc.Stations
                where s.id == stationID
                select s).SingleOrDefault();
        }
        /// <summary>
        /// Looks up a Video object from a video ID
        /// </summary>
        /// <param name="videoID">The ID of the video that is required</param>
        /// <returns>A video object with the corresponding ID</returns>
        static public Video GetVideoByID(int videoID)
        {
            Video video =
                (from v in DataService.ddc.Videos
                 where v.id == videoID
                 select v).SingleOrDefault();

            return video;
        }
        static public bool IsUserAdmin(int stationId, int userId)
        {
            int? access =
                (from u in DataService.ddc.WebUserRoles
                 where u.Station_id == stationId && u.WebUser_id == userId
                 select u.access).SingleOrDefault();

            if (access.HasValue && access > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        static public List<Station> GetStationsWhereAdminIs(int userId)
        {
            List<Station> stations =
                (from wur in DataService.ddc.WebUserRoles
                 where wur.WebUser_id == userId && wur.access >= 1
                 select wur.Station).ToList();

            return stations;
        }
        static public void AddVideoRating(int videoId, int rating)
        {
            Video video = StationService.GetVideoByID(videoId);

            video.ratingSum = video.ratingSum + rating;
            video.ratingCount = video.ratingCount + 1;

            DataService.ddc.SubmitChanges();
        }

        static public List<Station> FindMostPopularStations()
        {
            List<Station> popularStations = (from s in DataService.ddc.Stations
                                             orderby (s.viewCount * (s.ratingCount > 0 ? (double)s.ratingSum/s.ratingCount : 0.5)) descending
                                             select s).Take(4).ToList();

            return popularStations;
        }

        static public List<Video> FindMostPopularVideos(int n)
        {
            List<Video> popularVideos = (from v in DataService.ddc.ScheduleItems
                                         where v.airDateTime > DateTime.Now.AddHours(-12)
                                         && v.airDateTime < DateTime.Now.AddHours(12)
                                         orderby (v.Video.viewCount * (v.Video.ratingCount > 0 ? (double)v.Video.ratingSum/v.Video.ratingCount : 0.5)) descending
                                         select v.Video).Take(n).ToList();
            return popularVideos;
        }

        static public List<Station> FindMostRecentStations()
        {
            List<Station> recentStations = (from s in DataService.ddc.Stations
                                            orderby s.createdDate descending
                                            select s).Take(4).ToList();
            return recentStations;
        }

        static public List<Video> FindMostPopularVideosOnStation(int stationID)
        {
            List<Video> popularVideosOnStation = (from v in DataService.ddc.ScheduleItems
                                                  where v.Station_id == stationID
                                                  && v.airDateTime > DateTime.Now.AddHours(-12)
                                                  && v.airDateTime < DateTime.Now.AddHours(12)
                                                  orderby (v.Video.viewCount * (v.Video.ratingCount > 0 ? (double)v.Video.ratingSum/v.Video.ratingCount : 0.5)) descending
                                                  select v.Video).Take(5).ToList();
            return popularVideosOnStation;
        }

        static public List<Comment> GetVideoComment(int videoId)
        {
            List<Comment> comment =
                (from c in DataService.ddc.Comments
                 where c.Video_id == videoId
                 orderby c.id descending
                 select c).ToList();
            return comment;
        }
        static public void AddVideoComment(string comment, int userId, int videoId)
        {
            Comment c = new Comment()
            {
                comment1 = comment,
                Video_id = videoId,
                WebUser_id = userId,
                WebUser = AccountService.GetUserByID(userId),
                spamReportCount = 0,
                commentTime = DateTime.Now
            };

            DataService.ddc.Comments.InsertOnSubmit(c);

            DataService.ddc.SubmitChanges();
        }

        static public Video GetCurrentShow(int stationID)
        {
            Video currentShow = (from v in DataService.ddc.ScheduleItems
                                 where v.Station_id == stationID &&
                                 v.airDateTime < DateTime.Now.AddHours(12) &&
                                 v.airDateTime > DateTime.Now.AddHours(-12)
                                 orderby v.airDateTime ascending
                                 select v.Video).FirstOrDefault() as Video;
            return currentShow;
        }

        static public int GetIdOfCurrentShow(int stationID)
        {
            int currentShowID = (from v in DataService.ddc.ScheduleItems
                                 where v.Station_id == stationID &&
                                 v.airDateTime < DateTime.Now.AddHours(12) &&
                                 v.airDateTime > DateTime.Now.AddHours(-12)
                                 orderby v.airDateTime ascending
                                 select v.id).FirstOrDefault();
            return currentShowID;
        }

        static public int GetSerieIdByVideoID(int videoID)
        {
            int serieID = (from v in DataService.ddc.Videos
                           where v.id == videoID
                           select v.Series_id).SingleOrDefault();
            return serieID;
        }

        static public string GetSerieNameByID(int serieID)
        {
            string serieName = (from s in DataService.ddc.Series
                                where s.id == serieID
                                select s.name).SingleOrDefault();
            return serieName;
        }
        static public List<WebUser> GetAdmins(int stationId)
        {
            List<WebUser> admins =
                (from wur in DataService.ddc.WebUserRoles
                where wur.Station_id == stationId &&
                wur.access > 0
                select wur.WebUser).ToList();

            return admins;
        }
        static public List<Video> GetReccomentation(int stationId)
        {
            List<Video> reccomendations =
                (from v in DataService.ddc.Videos
                 where v.Station_id == stationId
                 select v).ToList();

                return reccomendations;
        }
        static public string GetVideoThumbnail(int videoId)
        {
            Video video = StationService.GetVideoByID(videoId);
            if (video.thumbnail == null)
            {
                return "/Content/Images/default_thumb.jpg";
            }
            else
            {
                return video.thumbnail;
            }
        }
        static public List<Station> GetStationsFromTo(int from, int to)
        {
            List<Station> stations = (from s in DataService.ddc.Stations
                                      orderby s.name
                                      select s).Skip(from).Take(to).ToList();


            return stations;
        }
    }
}
